home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / KmdOps / emtrace.c next >
Encoding:
C/C++ Source or Header  |  1990-08-30  |  10.2 KB  |  415 lines

  1.  
  2. /*  C O P Y R I G H T   N O T I C E :                                     */
  3. /* Copyright 1986 Eric Jul.  May not be used for any               */
  4. /* purpose without written permission from the author.              */
  5.  
  6.  
  7. /*
  8.  * $Header$
  9.  * INTERFACE:    Takes KMD parameters, see error msg.
  10.  *
  11.  * FUNCTION:    Execute single KMD trace requests.
  12.  *
  13.  * IMPORTS:    loads, see #include
  14.  *
  15.  * EXPORTS:    Nothing.
  16.  *
  17.  * DESIGN:    Send start trace message to the traced process and then
  18.  *              repeatedly receive and print data until stop trace
  19.  *              message arrives.
  20.  *
  21.  */
  22. #undef integer
  23. #include <sys/types.h>
  24. #include <sys/socket.h>
  25. #include <netinet/in.h>
  26. #include <stdio.h>
  27.  
  28. #define mSUCCESS(X) (((X) & 7) == 1)
  29.  
  30. typedef int KKStatus;
  31.  
  32. #define MAXMESSAGESIZE        1000
  33. #include "Kernel/h/stdTypes.h"
  34. #include "Kernel/h/kmdDefs.h"
  35. #include "Kernel/h/emPorts.h"
  36. #include <netdb.h>
  37. #include <signal.h>
  38.  
  39. #define endcase break
  40.  
  41. int                  talkSock;
  42. struct sockaddr_in   destSockDescr = {AF_INET};
  43. int                  prodTime = 1;
  44. int                 tracing = 0;
  45. char                *tracename;
  46. int                 machineNameGiven = 0;
  47. char                *machineName;
  48. int                 OK;
  49. static int          pid = 0;
  50. static int          pidGiven = 0;
  51. int                 MType, MInt;
  52. char                MString[5000];
  53.  
  54. /* Define signal handlers */
  55.  
  56. void PipeHandler(sig)
  57. int sig;
  58. {
  59.     printf("SIGPIPE>>> The connection to the process broke.\n");
  60.     printf("Terminating\n");
  61.     exit(sig);
  62. }
  63.  
  64. void TerminationHandler(sig)
  65. int sig;
  66.     if (sig != 0) {
  67.     printf("Terminating trace due to signal %d.\n", sig);
  68.     }
  69.     KMDSend(talkSock, KMDCLASTMSG, 0, "done");
  70.     shutdown(talkSock, 1);
  71.     while(mSUCCESS(KMDReceive(talkSock, &MType, &MInt, MString)));
  72.     close(talkSock);
  73.     exit(sig);
  74. };
  75.  
  76.  
  77. void Prodder()
  78. /* Prods the kernel by sending a SIGURG signal.
  79.    Exponential backoff.
  80.  */
  81. {
  82. /*    kill(pid, SIGURG); */
  83.     prodTime += prodTime;
  84.     alarm(prodTime);
  85. }
  86.  
  87. void SendTraceStart(fTraceName, fTraceLevel, fUseStdOut)
  88. char    *fTraceName;
  89. int     fTraceLevel;
  90. int     fUseStdOut;
  91. {
  92.     KKStatus kstat;    
  93.     if (fUseStdOut) {
  94.     kstat = KMDSend(talkSock, KMDCTRACESTDOUT, fTraceLevel, fTraceName);
  95.     } else {
  96.     kstat = KMDSend(talkSock, KMDCTRACE, fTraceLevel, fTraceName);
  97.     }
  98.     
  99.     if (! mSUCCESS( kstat ) ) {
  100.         printf("Send start trace msg failure, kstat = 0x%08x\n", kstat);
  101.     perror("send");
  102.         exit(1);
  103.     };
  104.  
  105. }
  106.  
  107. void SendTraceStop(fTraceName, fTraceLevel, fUseStdOut)
  108. char    *fTraceName;
  109. int     fTraceLevel;
  110. int     fUseStdOut;
  111. {
  112.     KKStatus kstat;    
  113.     if (fUseStdOut) {
  114.     kstat = KMDSend(talkSock, KMDCUNTRACESTDOUT, fTraceLevel, fTraceName);
  115.     } else {
  116.     kstat = KMDSend(talkSock, KMDCUNTRACE, fTraceLevel, fTraceName);
  117.     }
  118.     
  119.     if (! mSUCCESS( kstat ) ) {
  120.         printf("Send stop trace msg failed, kstat = 0x%08x\n", kstat);
  121.     perror("send");
  122.         exit(1);
  123.     };
  124. }
  125.  
  126. main(argc, argv)
  127. int         argc;
  128. char        *argv[];
  129. {
  130.   int               OK;
  131.   char              EPName[50];
  132.   static int        i, EPLNN, Level;
  133.   KKStatus          kstat;
  134.   static char       StdTrace[] = "DebugMsg";
  135.   char              myHostName[100];
  136.   struct hostent   *myHost;
  137.   int               machineNameGiven = 0;
  138.   int               argCount = argc;
  139.   
  140.     tracename = StdTrace;           /* default */
  141.     Level = 3;                      /* default */
  142.     
  143.     if (argc == 2)
  144.         if (!strcmp(argv[1], "usage")) {
  145.         printf("Usage: trace <options>\n");
  146.                 printf("    -T <name>\tStart tracing\n");
  147.                 printf("    -S <name>\tStart the trace; output to kernel stdout\n");
  148.                 printf("             \t(to stop, use -C in a later call)\n");
  149.         printf("    -l <level>\tSet the trace level for -S & -T\n");
  150.         printf("              \t(must preceed -T and -S)\n");
  151.         printf("    -M <name> \tTrace kernel on the named machine\n");
  152.         printf("    -m <name> \tTrace kernel on the named machine\n");
  153.         printf("    -x [<level>]\tDebugMsg trace\n");
  154.         printf("    -t [<level>]\tMMTrace\n");
  155.                 printf("The program waits until it or the kernel dies.\n");
  156.         exit(0);
  157.         }
  158.  
  159.     /*
  160.      * Parse command line options
  161.      */
  162.     while (argc > 1 && argv[1][0] == '-') {
  163.         switch (argv[1][1]) {
  164.         case 'N':        /* Set logical node number */
  165.             if (argv[1][2] == '\0') {
  166.                 EPLNN = atoi(argv[2]);
  167.                 argc--;
  168.                 argv++;
  169.             } else
  170.                 EPLNN = atoi(&argv[1][2]);
  171.                         
  172.             break;
  173.         case 'x':
  174.                 case 'n':
  175.                 case 'C':
  176.         case 't':
  177.         case 'l':
  178.                 case 'T':
  179.                 case 'S':
  180.             if (argv[1][2] == '\0') {
  181.                 argc--;
  182.                 argv++;
  183.             }
  184.             break;
  185.         case 'P':       /* Set pid, cancel LNN usage. */
  186.             if (argv[1][2] == '\0') {
  187.                 pid = atoi(argv[2]);
  188.                 argc--;
  189.                 argv++;
  190.             } else
  191.                 pid = atoi(&argv[1][2]);
  192.                         pidGiven = 1;
  193.             printf("warning: -P ignored.\n");
  194.             break;
  195.                 case 'M':
  196.                 case 'm':
  197.                         if (argv[1][2] == '\0') {
  198.                 strcpy(myHostName, argv[2]);
  199.                 argc--;
  200.                 argv++;
  201.             } else strcpy(myHostName, &argv[1][2]);
  202.             machineNameGiven ++;
  203.                         break;
  204.    
  205.                 default:
  206.                         printf("Warning: Unknown option: %c ignored.\n",
  207.                 argv[1][1]);
  208.                         break;
  209.  
  210.         }
  211.         argc--;
  212.         argv++;
  213.     }
  214.     argv -= (argCount - argc);  /* restore for next pass */
  215.     argc = argCount;
  216.     
  217.     /* Set termination handler. */
  218.     signal(SIGHUP, TerminationHandler);
  219.     signal(SIGQUIT, TerminationHandler);
  220.     signal(SIGINT, TerminationHandler);
  221.     signal(SIGBUS, TerminationHandler);
  222.     signal(SIGSEGV, TerminationHandler);
  223.     signal(SIGTERM, TerminationHandler);
  224.     
  225.     signal(SIGPIPE, PipeHandler);
  226.     signal(SIGALRM, Prodder);
  227.     
  228.     talkSock = socket(AF_INET, SOCK_STREAM, 0, 0);
  229.     if (talkSock < 0) {
  230.                 perror("trace: socket");
  231.                 exit(1);
  232.     }
  233.  
  234.     if (! machineNameGiven) {
  235.     if (gethostname(myHostName, 100) < 0) {
  236.         perror("trace: gethostname");
  237.         exit(1);
  238.     }
  239.     }
  240.     myHost = gethostbyname(myHostName);
  241.     if (myHost == NULL) {
  242.             perror("trace: gethostbyname");
  243.             exit(1);
  244.     }
  245.  
  246.     bcopy(myHost->h_addr, &destSockDescr.sin_addr, myHost->h_length);
  247.  
  248.     {
  249.       char *emplanename;
  250.       int emPlane = 0;
  251.       int emPort = EMKERNELDEFAULTPORTNUMBER;
  252.       struct servent   *myService;
  253.       emplanename = (char *) getenv("EMPLANE");
  254.       if (emplanename != NULL) emPlane = atoi(emplanename);
  255. #ifdef DIKU
  256.       myService = getservbyname(EMKERNELSERVICEPORT, "tcp");
  257.       if(myService)
  258.     emPort = ntohs(myService->s_port);
  259. #endif
  260.       destSockDescr.sin_port = htons(emPort + emPlane*4 + 1);
  261.     }
  262.  
  263.     if (connect(talkSock, &destSockDescr, sizeof(destSockDescr)) == -1) {
  264.                 perror("trace: connect");
  265.                 exit(1);
  266.     }
  267.  
  268.  
  269.     if ( KMDTest )
  270.         printf("Connected to %d\n", ntohs(destSockDescr.sin_port));
  271.     
  272.     if (!mSUCCESS(KMDReceive(talkSock, &MType, &MInt, MString))) {
  273.         printf("Connection reply failed.\n");
  274.     TerminationHandler(0);
  275.     }
  276.     printf("%s", MString);
  277.     /* Start trace/*/
  278.     /*
  279.      * Parse command line options again.
  280.      */
  281.     while (argc > 1 && argv[1][0] == '-') {
  282.         switch (argv[1][1]) {
  283.         case 'N':        /* Set logical node number */
  284.             if (argv[1][2] == '\0') {
  285.                 argc--;
  286.                 argv++;
  287.             };                        
  288.             break;
  289.         case 'x':
  290.                         tracename = "DebugMsg";
  291.             if (argv[1][2] == '\0') {
  292.                 Level = atoi(argv[2]);
  293.                 argc--;
  294.                 argv++;
  295.             } else
  296.                 Level = atoi(&argv[1][2]);
  297.                         SendTraceStart(tracename, Level, FALSE);
  298.             break;
  299.         case 't':
  300.             if (argv[1][2] == '\0') {
  301.                 Level = atoi(argv[2]);
  302.                                 tracename = "MMTraceMsg";
  303.                 argc--;
  304.                 argv++;
  305.             } else {
  306.                                 tracename = "MMTraceMsg";
  307.                 Level = atoi(&argv[1][2]);
  308.             }
  309.                         SendTraceStart(tracename, Level, FALSE);
  310.             break;
  311.         case 'l':
  312.             if (argv[1][2] == '\0') {
  313.                 Level = atoi(argv[2]);
  314.                 argc--;
  315.                 argv++;
  316.             } else
  317.                 Level = atoi(&argv[1][2]);
  318.             break;
  319.                 case 'n':
  320.                 case 'T':
  321.                         if (argv[1][2] == '\0') {
  322.                 SendTraceStart(argv[2], Level, FALSE);
  323.                 argc--;
  324.                 argv++;
  325.             } else SendTraceStart(&argv[1][2], Level, FALSE);
  326.                         break;
  327.                 case 'S':
  328.                         if (argv[1][2] == '\0') {
  329.                 SendTraceStart(argv[2], Level, TRUE);
  330.                 argc--;
  331.                 argv++;
  332.             } else SendTraceStart(&argv[1][2], Level, TRUE);
  333.                         break;
  334.                 case 'C':
  335.                         if (argv[1][2] == '\0') {
  336.                 SendTraceStop(argv[2], Level, TRUE);
  337.                 argc--;
  338.                 argv++;
  339.             } else SendTraceStop(&argv[1][2], Level, TRUE);
  340.                         break;
  341.  
  342.         case 'P':       /* Set pid, cancel LNN usage. */
  343.             if (argv[1][2] == '\0') {
  344.                 argc--;
  345.                 argv++;
  346.             }
  347.             break;
  348.                 case 'M':
  349.                 case 'm':
  350.             if (argv[1][2] == '\0') {
  351.                 argc--;
  352.                 argv++;
  353.             }
  354.                         break;
  355.                 default:
  356.                         break;
  357.  
  358.         }
  359.         argc--;
  360.         argv++;
  361.     }
  362.     tracing = 1;
  363.     
  364.     fflush(stdout);
  365.     OK = 1;
  366.     while (OK==1) {
  367.     if (!mSUCCESS(KMDReceive(talkSock, &MType, &MInt, MString))) {
  368.         /* Something went wrong, so quit */
  369.         printf("Trace closed\n");
  370.         TerminationHandler(0);
  371.     }
  372.         if ( KMDTest ) {
  373.             printf("Msg from: %d, (%d, %d, %s)\n", talkSock,
  374.                 MType, MInt, MString);
  375.             fflush(stdout);
  376.         };
  377.         
  378.         switch ( MType ) {
  379.         
  380.         case KMDCDATA:
  381.             printf("%s", MString);
  382.             fflush(stdout);
  383.         endcase;
  384.         
  385.     case KMDREADLINE:
  386.         {
  387.         char foo[256];
  388.         printf("(edb) ");
  389.         gets(foo);
  390.         KMDSend(talkSock, KMDREADLINEANS, 0, foo);        
  391.         }
  392.     endcase;
  393.     
  394.         case KMDCUNTRACE:
  395.             OK = 0;         /* quit */
  396.         endcase;
  397.         
  398.         case KMDCERRMSG:
  399.             printf("Error: %s\n", MString);
  400.             fflush(stdout);
  401.             TerminationHandler(0);
  402.             OK = 0;         /* quit */
  403.         endcase;
  404.         
  405.         case KMDCLASTMSG:
  406.             printf("%s", MString);
  407.             TerminationHandler(0);
  408.         default:
  409.             printf("**** KMD error: Warning, bad msgtype: %d \n", MType);
  410.         };
  411.     };
  412.     TerminationHandler(0);
  413. }
  414.